﻿using System;
using Microsoft.Maps.MapControl;
using System.Windows;
using System.Collections.Generic;
using MyFloridaHouse.ServiceConn.DistrBldrSvcRef;
using MyFloridaHouse.libSvUtilities.Logging;
using MyFloridaHouse.libSvOpenDistricts.Criteria;
using System.Collections.ObjectModel;

namespace MyFloridaHouse.libSvOpenDistricts.DataService
{
    public delegate void ServiceDALGetRegionListShapesCompletedEventHandler(RegionsShapesSTO args);

    public struct PendingGetRegionListShapesRequest
    {
        public double zoomLevel;
        public int layerID;
        public List<int> regionIDList;
    }

    public partial class ServiceDAL
    {
        public static event ServiceDALGetRegionListShapesCompletedEventHandler GetRegionListShapesCompleted;

        public void GetRegionListShapes(double zoomLevel, int layerID, List<int> regionIDList)
        {
            try
            {
                if (GetRegionListShapesCount(layerID) > 0)
                {
                    PendingGetRegionListShapesRequest rqst = new PendingGetRegionListShapesRequest();
                    rqst.zoomLevel = zoomLevel;
                    rqst.layerID = layerID;
                    rqst.regionIDList = regionIDList;
                    addGetRegionListShapesPendingRequest(layerID, rqst);
                }
                else
                {


                    ObservableCollection<int> newRegionIDList = new ObservableCollection<int>();
                    foreach (var rgn in regionIDList)
                    {
                        newRegionIDList.Add(rgn);
                    }

                    //MyDistrictBuilderServiceClient proxy = new MyDistrictBuilderServiceClient(myRelativeBinding, myRelativeCensusDataServiceAddress);
					var proxy = new DistrBldrClient(_relativeBindingName);
                    proxy.GetRegionListShapesCompleted += ServiceGetRegionListShapesCompleted;
                    proxy.GetRegionListShapesAsync(zoomLevel, layerID, newRegionIDList);
                    incrementGetRegionListShapesActiveCount(layerID);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ServiceGetRegionListShapesCompleted(object sender, GetRegionListShapesCompletedEventArgs args)
        {
            decrementGetRegionListShapesActiveCount(args.Result.layerID);
            if (!IsError("GetRegionListShapesCompleted", args.Error, args.Result, args.Result.errorMessage))
            {

                // only bother mapping if this is the last request we sent
                if (IsGetRegionListShapesPendingRequest(args.Result.layerID))
                {
                    PendingGetRegionListShapesRequest rqst = removeGetRegionListShapesPendingRequest(args.Result.layerID);
                    GetRegionListShapes(rqst.zoomLevel, rqst.layerID, rqst.regionIDList);
                }
                else
                {
                    RaiseGetRegionListShapesCompleted(this, args.Result);
                }

            }
        }

        private static void RaiseGetRegionListShapesCompleted(object sender, RegionsShapesSTO sto)
        {
            if (GetRegionListShapesCompleted != null)
            {
                GetRegionListShapesCompleted(sto);
            }
            else
            {
                // todo: Log this error
                throw (new NotImplementedException("No Subscribers to GetRegionListShapesCompleted Event"));
            }
        }

        public int GetRegionListShapesRequestActiveCount
        {
            get { return GetRegionListShapesCountByLayer.Count; }

        }

        private Dictionary<int, int> GetRegionListShapesCountByLayer = new Dictionary<int, int>();
        private void incrementGetRegionListShapesActiveCount(int layerID)
        {
            if (GetRegionListShapesCountByLayer.ContainsKey(layerID))
            {
                GetRegionListShapesCountByLayer[layerID] = GetRegionListShapesCountByLayer[layerID] + 1;
            }
            else
            {
                GetRegionListShapesCountByLayer.Add(layerID, 1);
            }
            NotifyPropertyChanged("GetRegionListShapesRequestActiveCount");
        }
        private void decrementGetRegionListShapesActiveCount(int layerID)
        {
            if (GetRegionListShapesCountByLayer.ContainsKey(layerID))
            {
                GetRegionListShapesCountByLayer[layerID] = GetRegionListShapesCountByLayer[layerID] - 1;
                if (GetRegionListShapesCountByLayer[layerID] == 0)
                {
                    GetRegionListShapesCountByLayer.Remove(layerID);
                }
            }
            else
            {
                // it's not in the list and we don't want it there, so don't do anything
                // however, we did expect something there so there is a problem
                Log.HandleInternalError("Error decrementing count of pending GetRegionListShapes requests, current count not found");
            }
            NotifyPropertyChanged("GetRegionListShapesRequestActiveCount");
        }
        private int GetRegionListShapesCount(int layerID)
        {
            if (GetRegionListShapesCountByLayer.ContainsKey(layerID))
            {
                return GetRegionListShapesCountByLayer[layerID];
            }
            else
            {
                return 0;
            }
        }

        public int GetRegionListShapesRequestPendingCount
        {
            get { return pendingGetRegionListShapesRequests.Count; }
        }

        private Dictionary<int, PendingGetRegionListShapesRequest> pendingGetRegionListShapesRequests = new Dictionary<int, PendingGetRegionListShapesRequest>();
        private void addGetRegionListShapesPendingRequest(int layerID, PendingGetRegionListShapesRequest pendingRequest)
        {
            if (pendingGetRegionListShapesRequests.ContainsKey(layerID))
            {
                pendingGetRegionListShapesRequests[layerID] = pendingRequest;

            }
            else
            {
                pendingGetRegionListShapesRequests.Add(layerID, pendingRequest);
            }
            NotifyPropertyChanged("GetRegionListShapesRequestPendingCount");
        }
        private PendingGetRegionListShapesRequest removeGetRegionListShapesPendingRequest(int layerID)
        {
            if (pendingGetRegionListShapesRequests.ContainsKey(layerID))
            {
                PendingGetRegionListShapesRequest pendingRequest = pendingGetRegionListShapesRequests[layerID];
                pendingGetRegionListShapesRequests.Remove(layerID);
                NotifyPropertyChanged("GetRegionListShapesRequestPendingCount");
                return pendingRequest;
            }
            else
            {
                // it's not in the list and we don't want it there, so don't do anything
                // however, we did expect something there so there is a problem
                Log.HandleInternalError("Error decrementing count of pending GetRegionListShapes requests, current count not found");
                return new PendingGetRegionListShapesRequest();
            }


        }
        private bool IsGetRegionListShapesPendingRequest(int layerID)
        {
            if (pendingGetRegionListShapesRequests.ContainsKey(layerID))
            {
                return true;
            }
            else
            {
                return false;
            }
        }


    }
}

